using AutoMapper;
using BaseData.API.Write.Applications.HospitalInformation.Command;
using BaseData.API.Write.Dtos;
using BaseData.Domain.HospitalInformation;
using BaseData.ErrorCode;
using BaseData.Infrastructure.Interfaces;
using MediatR;
using Microsoft.EntityFrameworkCore;

namespace BaseData.API.Write.Applications.HospitalInformation.Commandhandler
{
    /// <summary>
    /// 医生级联查询命令处理器
    /// </summary>
    public class DoctorsCascadeQueryCommandHandler : IRequestHandler<DoctorsCascadeQueryCommand, ApiResult<ApiPaging<DoctorsWithDepartmentDTO>>>
    {
        private readonly IBaseRepository<Doctors> doctorsRepository;
        private readonly IBaseRepository<Departments> departmentsRepository;
        private readonly IMapper mapper;

        public DoctorsCascadeQueryCommandHandler(
            IBaseRepository<Doctors> doctorsRepository,
            IBaseRepository<Departments> departmentsRepository,
            IMapper mapper)
        {
            this.doctorsRepository = doctorsRepository;
            this.departmentsRepository = departmentsRepository;
            this.mapper = mapper;
        }

        public async Task<ApiResult<ApiPaging<DoctorsWithDepartmentDTO>>> Handle(DoctorsCascadeQueryCommand request, CancellationToken cancellationToken)
        {
            var result = new ApiResult<ApiPaging<DoctorsWithDepartmentDTO>>
            {
                Code = ApiEnum.查询成功,
                Message = ApiEnum.查询成功.ToString()
            };

            try
            {
                // 构建医生查询条件
                var doctorsQuery = doctorsRepository.GetAll().Where(d => !d.Isdelete);

                // 应用过滤条件
                if (!string.IsNullOrEmpty(request.DoctorName))
                {
                    doctorsQuery = doctorsQuery.Where(d => d.DoctorName.Contains(request.DoctorName));
                }

                if (request.DepartmentId.HasValue)
                {
                    doctorsQuery = doctorsQuery.Where(d => d.DepartmentId == request.DepartmentId.Value);
                }

                if (!string.IsNullOrEmpty(request.HospitalCampus))
                {
                    doctorsQuery = doctorsQuery.Where(d => d.HospitalCampus.Contains(request.HospitalCampus));
                }

                if (request.DoctorStatus.HasValue)
                {
                    doctorsQuery = doctorsQuery.Where(d => d.DoctorStatus == request.DoctorStatus.Value);
                }

                // 如果有父级科室ID的过滤条件，需要先查询子科室
                if (request.ParentDepartmentId.HasValue)
                {
                    var childDepartmentIds = await GetChildDepartmentIds(request.ParentDepartmentId.Value);
                    doctorsQuery = doctorsQuery.Where(d => childDepartmentIds.Contains(d.DepartmentId));
                }

                // 获取总数
                var totalCount = await doctorsQuery.CountAsync(cancellationToken);
                var pageCount = (int)Math.Ceiling((double)totalCount / request.PageSize);

                // 分页查询医生数据
                var doctors = await doctorsQuery
                    .OrderBy(d => d.DoctorId)
                    .Skip((request.PageIndex - 1) * request.PageSize)
                    .Take(request.PageSize)
                    .ToListAsync(cancellationToken);

                // 构建结果数据
                var resultData = new List<DoctorsWithDepartmentDTO>();

                foreach (var doctor in doctors)
                {
                    var doctorDto = mapper.Map<DoctorsWithDepartmentDTO>(doctor);
                    
                    // 获取科室信息
                    var department = await departmentsRepository.GetAll()
                        .FirstOrDefaultAsync(d => d.DepartmentId == doctor.DepartmentId && !d.Isdelete, cancellationToken);

                    if (department != null)
                    {
                        doctorDto.DepartmentInfo = mapper.Map<DepartmentInfoDTO>(department);
                        
                        // 如果有父级科室，获取父级科室信息
                        if (department.parentId.HasValue)
                        {
                            var parentDepartment = await departmentsRepository.GetAll()
                                .FirstOrDefaultAsync(d => d.DepartmentId == department.parentId.Value && !d.Isdelete, cancellationToken);
                            
                            if (parentDepartment != null)
                            {
                                doctorDto.DepartmentInfo.ParentDepartment = mapper.Map<DepartmentInfoDTO>(parentDepartment);
                            }
                        }
                    }

                    resultData.Add(doctorDto);
                }

                // 构建分页结果
                var paging = new ApiPaging<DoctorsWithDepartmentDTO>
                {
                    TotalCount = totalCount,
                    PageCount = pageCount,
                    Data = resultData
                };

                result.Data = paging;
            }
            catch (Exception ex)
            {
                result.Code = ApiEnum.查询失败;
                result.Message = $"查询失败：{ex.Message}";
                result.Data = new ApiPaging<DoctorsWithDepartmentDTO>
                {
                    TotalCount = 0,
                    PageCount = 0,
                    Data = new List<DoctorsWithDepartmentDTO>()
                };
            }

            return result;
        }

        /// <summary>
        /// 递归获取子科室ID列表
        /// </summary>
        /// <param name="parentId">父级科室ID</param>
        /// <returns>子科室ID列表（包含自身）</returns>
        private async Task<List<int>> GetChildDepartmentIds(int parentId)
        {
            var result = new List<int> { parentId };
            
            var childDepartments = await departmentsRepository.GetAll()
                .Where(d => d.parentId == parentId && !d.Isdelete)
                .ToListAsync();

            foreach (var child in childDepartments)
            {
                var childIds = await GetChildDepartmentIds(child.DepartmentId);
                result.AddRange(childIds);
            }

            return result;
        }
    }
}
